#include "avsdeclib.h"
#include "global.h"
#include <time.h>
#include <sys/timeb.h>

#include <wchar.h>
#include <tchar.h>

#define BUFLEN  (1*1024*1024)
//#define BUFLEN (100*1000)
#define SEQENCE_END_CODE     0X000001B1
//#define PRINTINFO
//#define WIN32
//#define _DEBUG
//#define _CONSOLE
//#define _MBCS
//#define HAVE_STDINT_H

static char *ARG_INPUTFILE = NULL;

void writeYUV(int width, int height, BYTE * pY,BYTE * pU, BYTE * pV, FILE *p_out)
{
	int i,j;
	int height_cr , width_cr;
	int sizeY,sizeUV;
	height_cr = height >>1;
	width_cr = width >>1;
	sizeY = width * height;
	sizeUV = width_cr * height_cr;
	
	
	/*for(i=0;i<sizeY;i++)
	fputc(pY[i],p_out);

	for(i=0;i<sizeUV;i++)
	fputc(pU[i],p_out);

	for(i=0;i<sizeUV;i++)
	fputc(pV[i],p_out);*/

	fwrite(pY, 1, sizeY, p_out);
	fwrite(pU, 1, sizeUV, p_out);
	fwrite(pV, 1, sizeUV, p_out);
	
	fflush( p_out  );
	
}

int wmain(int argc, WCHAR* argv[])
{
    FILE *in_file;	//<Pointer to AVS file
    FILE *p_out;    //<Pointer to YUV file
    int ii, jj;
    BYTE *pY, *pU, *pV; 	//<y u v buffer
    unsigned char * pbData;	
    unsigned char * const enc_buf = (unsigned char *) malloc(BUFLEN);
    int length, nouse_len, left;
    int dwDataLen;
    char ofname[256] = "";
	char temp[256]="";
    int framenum = 0;
    int dwReadLen;
	//index in file to be decoded
    int index = 0;
    int start;
    int tempi = 0;
	
	int leftLen, frameLen, noUseDataLen, len;
	/////////////////////////////////TIME MEASUREMENT
    /*time_t ltime1;				     //<for time measurement
    time_t ltime2;*/
#ifdef WIN32
    struct _timeb tstruct1;
    struct _timeb tstruct2;
#else
    struct timeb tstruct1;
    struct timeb tstruct2;
#endif
    int tmp_time; 				  //<time used by decoding the last frame
/*#ifdef WIN32
    _ftime (&tstruct1);			  //<start time ms
#else
    ftime (&tstruct1);			  //<start time ms
#endif*/
    /*time( &ltime1 );				  //<start time s*/
	///////////////////////////////////File handle
    if (argc != 2) {
        fprintf(stderr, "Wrong application parameter\n");
        return 0;
    }
	sprintf(temp,"%S",argv[1]);
    ARG_INPUTFILE = temp;
    if (enc_buf == NULL) {
        //perror("Memory not sufficient.");
		printf("Memory not sufficient.");
        return 0;
    }
    pbData = enc_buf;
	
    in_file = fopen(ARG_INPUTFILE, "rb");
	
    if (in_file == NULL) {
        fprintf(stderr, "Error opening input file %s\n", ARG_INPUTFILE);
        return 0;
    }
	/*if ((p_OUT=fopen("D:\\avs\\OUT2.txt","w"))==0)             // append new statistic at the end
	{
	//snprintf(errortext, ET_SIZE, "Error open file %s!",TRACEFILE);
	//	error(errortext,500);
}*/
#if DEBUG_MODE
    printf("Open file %s\n", ARG_INPUTFILE);
#endif
    len = fread(enc_buf, 1, 160, in_file); //<read some bit from file
	leftLen = len;
    pbData = enc_buf;
    InitAVSDec();
    sprintf(ofname, "%s.yuv", ARG_INPUTFILE);
	if ((p_out=fopen(ofname,"wb"))==0)
	{
        printf("Error open file %s ",ofname);
	}
	/////////////////////////////////////////////
	
   	//int leftLen, frameLen, noUseDataLen, len;
#if PRINTINFO
	printf("Start decoding.....\n");
#endif
	
    ///////////////////////////////////////////////////////
    //Main loop
    do{
		
		if (GetOneFrameBitsFromBuffer(
			pbData, (int) leftLen,
			(int *) &frameLen,
			(int *) &noUseDataLen) != 1) {
			memcpy(enc_buf, enc_buf + (len - leftLen), leftLen);
			
			/* len = leftLen; */
			if ((len = fread(enc_buf + leftLen, 1, 
				BUFLEN - leftLen, in_file)) <= 0)
				break;
			len += leftLen;
			leftLen = len;
			pbData = enc_buf;
			continue;
		}
		
		DecOneFrameFromBuffer(pbData + noUseDataLen, frameLen, &pY,
			&pU, &pV);
		//writeYUV(strmInfo.SeqInfo.dwWidth, strmInfo.SeqInfo.dwHeight, pY, pU, pV, p_out);
		//////////////////////////////////
		//set frame number to stop...
		if(framenum==200) 
			break;
		framenum ++;
		
		
		pbData += frameLen;
		leftLen -= frameLen;
		printf("Decoding Frame num %d\n",framenum);
		//	frameLen = fread(buffer, 1, YUVlen, fp_YUV);
		
    }while ((*(DWORD *) pbData) != SEQENCE_END_CODE);
	
    free(enc_buf);
	//	fclose(   p_OUT   );
    CloseAVSDec();
	///////////////////////////////////////////////TIME
#ifdef DEBUG_MODE
/*#ifdef WIN32
	_ftime (&tstruct2);   // end time ms
#else
	ftime (&tstruct2);    // end time ms
#endif*/
	/*
	time( &ltime2 );                                // end time sec
		tmp_time=(ltime2*1000+tstruct2.millitm) - (ltime1*1000+tstruct1.millitm);*/
	
#if PRINTINFO
	printf("Clip Width                  : %d pix\n",strmInfo.SeqInfo.dwWidth);
	printf("Clip Height                 : %d pix\n",strmInfo.SeqInfo.dwHeight);
	printf("Frame rate                  : %f fps\n",strmInfo.SeqInfo.fFrameRate);
	/*printf("Total spend Time            : %d ms\n", tmp_time);*/
	printf("Total decode frame num      : %d\n",framenum+1);
	printf("Decoding Speed              : %d fps\n",(framenum+1)*1000/tmp_time);
	printf("Decoding finished\n");
#endif
#endif
	///////////////////////////////////////////////
    return 0;
}
